package org.budo.mybatis.dao.statement.builder.impl;

import org.apache.ibatis.session.Configuration;
import org.budo.mybatis.dao.statement.builder.creator.DeleteByIdStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.DeleteByIdsStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.FindByColumnsStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.FindByExampleStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.FindByIdStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.ListByColumnsStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.ListByIdsStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.SaveBatchStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.SaveIgnoreNullStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.SaveStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.UpdateColumnsStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.UpdateIgnoreNullStatementCreator;
import org.budo.mybatis.dao.statement.builder.creator.UpdateStatementCreator;
import org.budo.mybatis.dao.statement.builder.util.StatementBuilderUtil;

/**
 * @author limingwei
 */
public class DefaultStatementBuilder extends AbstractStatementBuilder {
    public synchronized void buildFindBySqlStatement(Configuration configuration, Class<?> entityType, String sql) {
        String statementId = this.sqlStatementId(sql);

        if (!configuration.hasStatement(statementId, false)) {
            String statementXml = _4 + "<select id=\"" + statementId + "\" " + this.resultMapOrResultType(configuration, entityType, sql) + " parameterType=\"map\">\n "//
                    + _8 + "<![CDATA[ \n" //
                    + _12 + sql + "\n"//
                    + _8 + " ]]>\n" //
                    + _4 + "</select>"; //
            StatementBuilderUtil.parseXmlMapper(configuration, "prepareFindBySqlStatement", statementXml);
        }
    }

    public synchronized void buildListBySqlStatement(Configuration configuration, Class<?> entityType, String sql) {
        String statementId = this.sqlStatementId(sql);
        if (!configuration.hasStatement(statementId, false)) {
            String statementXml = _4 + "<select id=\"" + statementId + "\" " + this.resultMapOrResultType(configuration, entityType, sql) + " parameterType=\"map\">\n"//
                    + _8 + "<![CDATA[\n"//
                    + _12 + sql + "\n"//
                    + _8 + " ]]>\n"//
                    + _4 + "</select>"; //
            StatementBuilderUtil.parseXmlMapper(configuration, "buildListBySqlStatement", statementXml);
        }
    }

    public synchronized void buildUpdateBySqlStatement(Configuration configuration, String sql) {
        String statementId = this.sqlStatementId(sql);

        if (!configuration.hasStatement(statementId, false)) {
            String statementXml = _4 + "<update id=\"" + statementId + "\" parameterType=\"map\">\n" //
                    + _8 + "<![CDATA[\n" //
                    + _12 + sql + "\n"//
                    + _8 + "]]>\n"//
                    + _4 + "</update>"; //
            StatementBuilderUtil.parseXmlMapper(configuration, "buildUpdateBySqlStatement", statementXml);
        }
    }

    public synchronized void buildDeleteBySqlStatement(Configuration configuration, String sql) {
        String statementId = this.sqlStatementId(sql);

        if (!configuration.hasStatement(statementId, false)) {
            String statementXml = _4 + "<delete id=\"" + statementId + "\" parameterType=\"map\">\n" //
                    + _8 + "<![CDATA[\n" //
                    + _12 + sql + "\n"//
                    + _8 + " ]]>\n" //
                    + _4 + "</delete>"; //
            StatementBuilderUtil.parseXmlMapper(configuration, "buildDeleteBySqlStatement", statementXml);
        }
    }

    public void buildFindByColumnsStatement(Configuration configuration, Class<?> entityType) {
        new FindByColumnsStatementCreator(configuration, this) //
                .buildStatement(entityType);
    }

    public void buildListByIdsStatement(Configuration configuration, Class<?> entityType) {
        new ListByIdsStatementCreator(configuration, this) //
                .buildStatement(entityType);
    }

    public void buildListByColumnsStatement(Configuration configuration, Class<?> entityType) {
        new ListByColumnsStatementCreator(configuration, this) //
                .buildStatement(entityType);
    }

    public void buildDeleteByIdsStatement(Configuration configuration, Class<?> entityType) {
        new DeleteByIdsStatementCreator(configuration, this).buildStatement(entityType);
    }

    public synchronized void buildDeleteByIdStatement(Configuration configuration, Class<?> entityType) {
        new DeleteByIdStatementCreator(configuration, this).buildStatement(entityType);
    }

    public void buildSaveBatchStatement(Configuration configuration, Class<?> entityType) {
        new SaveBatchStatementCreator(configuration, this).buildStatement(entityType);
    }

    public synchronized void buildSaveIgnoreNullStatement(Configuration configuration, Class<?> entityType) {
        new SaveIgnoreNullStatementCreator(configuration, this).buildStatement(entityType);
    }

    public void buildSaveStatement(Configuration configuration, Class<?> entityType) {
        new SaveStatementCreator(configuration, this).buildStatement(entityType);
    }

    public synchronized void buildUpdateStatement(Configuration configuration, Class<?> entityType) {
        new UpdateStatementCreator(configuration, this).buildStatement(entityType);
    }

    public synchronized void buildUpdateIgnoreNullStatement(Configuration configuration, Class<?> entityType) {
        new UpdateIgnoreNullStatementCreator(configuration, this).buildStatement(entityType);
    }

    public synchronized void buildUpdateColumnsStatement(Configuration configuration, Class<?> entityType) {
        new UpdateColumnsStatementCreator(configuration, this).buildStatement(entityType);
    }

    public synchronized void buildFindByExampleStatement(Configuration configuration, Class<?> entityType) {
        new FindByExampleStatementCreator(configuration, this) //
                .buildStatement(entityType);
    }

    public synchronized void buildFindByIdStatement(Configuration configuration, Class<?> entityType) {
        new FindByIdStatementCreator(configuration, this) //
                .buildStatement(entityType);
    }

    @Override
    public synchronized void buildListBySqlWithResultMapIdStatement(Configuration configuration, String resultMapId, String sql) {
        String statementId = this.sqlStatementId(resultMapId + "-" + sql);
        if (!configuration.hasStatement(statementId, false)) {
            String statementXml = _4 + "<select id=\"" + statementId + "\" resultMap=\"" + resultMapId + "\" parameterType=\"map\">\n"//
                    + _8 + "<![CDATA[\n"//
                    + _12 + sql + "\n"//
                    + _8 + " ]]>\n"//
                    + _4 + "</select>"; //
            StatementBuilderUtil.parseXmlMapper(configuration, "buildListBySqlWithResultMapIdStatement", statementXml);
        }
    }

    @Override
    public void buildFindBySqlWithResultMapIdStatement(Configuration configuration, String resultMapId, String sql) {
        String statementId = this.sqlStatementId(resultMapId + "-" + sql);
        if (!configuration.hasStatement(statementId, false)) {
            String statementXml = _4 + "<select id=\"" + statementId + "\" resultMap=\"" + resultMapId + "\" parameterType=\"map\">\n"//
                    + _8 + "<![CDATA[\n"//
                    + _12 + sql + "\n"//
                    + _8 + " ]]>\n"//
                    + _4 + "</select>"; //
            StatementBuilderUtil.parseXmlMapper(configuration, "buildFindBySqlWithResultMapIdStatement", statementXml);
        }
    }
}